package com.benyi.util;

import java.math.BigDecimal;

public class Calculate { 
	
	public static int cal(String exp){
		if(exp==null || exp.length()==0){
			return 0;
		}
		int kh=exp.indexOf("(");
		if(kh>=0){
			int to=toMatch(exp,'(',')',kh+1);
			if(to<0){
				return -1;
			}
			String m1=exp.substring(kh+1,to); //获取完整的 括号内表达式
			int v=cal(m1);
			String m=exp.substring(0,kh)+ String.valueOf(v) +exp.substring(to+1);
			return cal(m);
		}else{
			boolean isDiv=false;
			int sub=exp.indexOf("/");
			if(sub<0){
				sub=exp.indexOf("*");
			}else{
				isDiv=true;
			}
			if(sub<0){
				int v=calAddAndSub(exp); //只有加减
				return v;
			}else{ //有乘除
				String n1=getPreNumber(exp,sub-1);
				String n2=getNumber(exp.substring(sub+1));
				String x1=exp.substring(0,sub-n1.length());
				String x2=exp.substring(sub+n2.length()+1);
				int v=0;
				if(isDiv){
					v=Integer.parseInt(n1) / Integer.parseInt(n2);
				}else{
					v=Integer.parseInt(n1) * Integer.parseInt(n2);
				} 
				exp=x1+String.valueOf(v)+x2;
				return cal(exp);
			}
		} 
	}
	
	private static int calAddAndSub(String exp){
		int v=0;
		char c;
		String n1=null; 
		for(int i=0;i<exp.length();i++){
			c=exp.charAt(i);
			if(c=='+' || c=='-'){
				if(c=='-' && i==0){
					continue;
				}
				if(n1==null){
					n1=exp.substring(0,i);
					if(n1==null || n1.length()==0){
						n1="0";
					}
					String left=exp.substring(i+1);
					String opn=getNumber(left);
					
					left=left.substring(opn.length());
					
					int v1=Integer.parseInt(n1);
					int v2=Integer.parseInt(opn);
					
					if(c=='+'){
						v=v1+v2;
					}else{
						v=v1-v2;
					}
					exp=String.valueOf(v)+left;
					return calAddAndSub(exp);
				}
			}
		}
		v=Integer.parseInt(exp);
		return v;
	}
	
	private static String getNumber(String exp){
		int index=-1;
		char c;
		for(int i=0;i<exp.length();i++){
			c=exp.charAt(i);
			if(c=='-' || c=='+' || c=='*' || c=='/'){
				index=i;
				break;
			}
		}
		if(index<0){
			index=exp.length();
		}
		return exp.substring(0,index);
	}
	
	private static String getPreNumber(String exp,int toIndex){
		int index=-1;
		char c;
		int i=toIndex;
		while(i>=0){
			c=exp.charAt(i);
			if(c=='-' || c=='+' || c=='*' || c=='/'){
				index=i;	
				if(index>0){
					index++; //不包括符合
				}
				break;
			}
			i--;
		}
		if(index<0){
			index=0;
		}
		if(index==1){
			index=0;
		}
		return exp.substring(index,toIndex+1);
	}
	
	private static int toMatch(String exp,char m1,char m2,int from){
		int n=1;
		int p=-1;
		for(int i=from;i<exp.length();i++){
			if(exp.charAt(i)==m1){
				n++;
			}else{
				if(exp.charAt(i)==m2){
					n--;
					if(n==0){
						p=i;
						break;
					}
				}
			}
		}
		return p;
	}  
	
	public static BigDecimal cal(String exp,int decs){ //decs 为小时点位数
		if(exp==null || exp.length()==0){
			return BigDecimal.ZERO;
		}
		int kh=exp.indexOf("(");
		if(kh>=0){
			int to=toMatch(exp,'(',')',kh+1);
			if(to<0){
				return BigDecimal.valueOf(-1L);
			}
			String m1=exp.substring(kh+1,to); //获取完整的 括号内表达式
			BigDecimal v=cal(m1,decs);
			String m=exp.substring(0,kh)+ String.valueOf(v) +exp.substring(to+1);
			return cal(m,decs);
		}else{
			boolean isDiv=false;
			int sub=exp.indexOf("/");
			if(sub<0){
				sub=exp.indexOf("*");
			}else{
				isDiv=true;
			}
			if(sub<0){
				BigDecimal value=calAddAndSub(exp,decs); //只有加减
				return value;
			}else{ //有乘除
				String n1=getPreNumber(exp,sub-1);
				String n2=getNumber(exp.substring(sub+1));
				String x1=exp.substring(0,sub-n1.length());
				String x2=exp.substring(sub+n2.length()+1);
				BigDecimal v1=new BigDecimal(n1);
				BigDecimal v2=new BigDecimal(n2);
				BigDecimal v=null;
				if(isDiv){
					v=v1.divide(v2,decs,BigDecimal.ROUND_HALF_EVEN);
				}else{
					v=v1.multiply(v2);
				} 
				exp=x1+v.toString()+x2;
				return cal(exp,decs);
			}
		} 
	}
	
	private static BigDecimal calAddAndSub(String exp,int desc){
		BigDecimal v;
		char c;
		String n1=null; 
		for(int i=0;i<exp.length();i++){
			c=exp.charAt(i);
			if(c=='+' || c=='-'){
				if(c=='-' && i==0){
					continue;
				}
				if(n1==null){
					n1=exp.substring(0,i);
					if(n1==null || n1.length()==0){
						n1="0";
					}
					String left=exp.substring(i+1);
					String opn=getNumber(left);
					
					left=left.substring(opn.length());
					
					BigDecimal v1=new BigDecimal(n1);
					BigDecimal v2=new BigDecimal(opn); 
					if(c=='+'){
						v=v1.add(v2); 
					}else{
						v=v1.subtract(v2);
					}
					exp=v.toString()+left;
					return calAddAndSub(exp,desc);
				}
			}
		}
		v=new BigDecimal(exp);
		return v;
	} 
	 
	
	public static void main(String []args){
		long t=System.currentTimeMillis();
		String exp="-1" ;//(10-(1-1*2/3))/3-1/6+(1+2+3)*(1+2)";
    	int i=0;
    	int v=0;
    	int n=1;//1000000;
    	BigDecimal b=new BigDecimal(0);
    	while(i<n){
    		b=cal(exp,2);
    		i++;
    	}
    	System.out.println(b+","+(System.currentTimeMillis()-t)); 
    	 
	}
	
}
